package net.edwardstx.hibernateutils;

import java.util.HashSet;
import java.util.Set;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.SettingsFactory;
import org.hibernate.ejb.InjectionSettingsFactory;
import org.slf4j.Logger;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
import org.slf4j.LoggerFactory;

public class HibernateDAOFactory { 
		private final Logger								logger					= LoggerFactory.getLogger(this.getClass().getName());
		private static Set<Class<? extends HibernateDTO>>	setOfHibernateDTOs		= new HashSet<Class<? extends HibernateDTO>>();
		private HibernateConfigurator						configurator			= null;
		private SessionFactory sessionFactory = null;
		protected static Set<Class<? extends HibernateDTO>> getHibernateDTOs(){
			return setOfHibernateDTOs;
		}
		
		/**
		 * Adds the specified DAO to the list of managed DAOs.
		 * 
		 * Note: This will require the current thread to obtain a lock on the specified Class object.
		 * @param hibernateDAOClassNew
		 */
		protected static void addManagedDAO(Class<? extends HibernateDAO> hibernateDAOClassNew){
			HibernateManagedDTOs hibernateManagedDTOs = hibernateDAOClassNew.getAnnotation(HibernateManagedDTOs.class);
			for(Class<? extends HibernateDTO> classManagedDTO : hibernateManagedDTOs.arrayOfClassesMannagedDTOs()){
				setOfHibernateDTOs.add(classManagedDTO);
			}
		}
		
		protected SessionFactory buildSessionFactory(){
			SettingsFactory settingsFactory = new InjectionSettingsFactory();
			AnnotationConfiguration annotationConfiguration = new AnnotationConfiguration( settingsFactory );
			annotationConfiguration = getConfigurator().configure(annotationConfiguration);
			annotationConfiguration.setProperty("hibernate.current_session_context_class","org.hibernate.context.ThreadLocalSessionContext");
			for(Class<? extends HibernateDTO> classManagedDTO : getHibernateDTOs()){
				annotationConfiguration.addAnnotatedClass(classManagedDTO);
			}
			return annotationConfiguration.buildSessionFactory();
		}
		
		public synchronized SessionFactory getEntityManagerFactory(){
			if(this.sessionFactory == null){
				this.sessionFactory = buildSessionFactory();
			}
			return this.sessionFactory;		
		}
		
		public HibernateDAOFactory(HibernateConfigurator configuratorNew){
			setConfigurator(configuratorNew);
		}

		public void setConfigurator(HibernateConfigurator configuratorNew) {
			this.configurator = configuratorNew;
		}

		public HibernateConfigurator getConfigurator() {
			return configurator;
		}

		public Logger getLogger() {
			return logger;
		}
}
